package client;

import client.NetMessages.ChatMessage;
import client.NetMessages.MovePacket;
import com.jme3.math.Vector3f;
import com.jme3.network.Client;
import com.jme3.network.ClientStateListener;
import com.jme3.network.ConnectionListener;
import com.jme3.network.HostedConnection;
import com.jme3.network.Message;
import com.jme3.network.MessageListener;
import com.jme3.network.Network;
import com.jme3.network.Server;
import com.jme3.network.serializing.Serializer;

/**
 *
 * @author Ben
 */
public class NetworkController
{
    Client child = null;    
    Server host = null;
    static LundWidget lund = new LundWidget();

    public class ClientStates implements ClientStateListener
    {
        public void clientConnected(Client c)
        {
            lund.printConsoleInfo("Client - " + c.getId() + " connected.");
            ObjectNetplayer net = new ObjectNetplayer(new Vector3f(0,0,0),"null",c);
        }
        
        public void clientDisconnected(Client c, DisconnectInfo info)
        {
            lund.printConsoleInfo("Client - " + c.getId() + " disconnected, reason: " + info.reason);
        }
    }
    
    public class ServerStates implements ConnectionListener
    {
        public void connectionAdded(Server s, HostedConnection c)
        {
            lund.printConsoleInfo("Client - " + c.getId() + " connected.");
            ObjectNetplayer net = new ObjectNetplayer(new Vector3f(0,0,0),"null",c);
        }
        
        public void connectionRemoved(Server s, HostedConnection c)
        {
            lund.printConsoleInfo("Client - " + c.getId() + " disconnected");
        }
    }
    
    public static void registerMessages()
    {
        Serializer.registerClass(ChatMessage.class);
        Serializer.registerClass(MovePacket.class);
    }
    
    public void sendChat(String message)
    {
        System.out.println(message);
        Message mess = new ChatMessage(message);
        mess.setReliable(true);
        if(child != null)
        {
            child.send(mess);
        }
        if(host != null)
        {
            host.broadcast(mess);
        }
    }
    
    public void sendMove(Vector3f loc, int ID)
    {
        Message mess = new MovePacket(loc,0,false,ID);
        mess.setReliable(true);
        if(child != null)
        {
            child.send(mess);
        }
        if(host != null)
        {
            host.broadcast(mess);
        }
    }
    
    public void syncAll(HostedConnection c)
    {
        Message mess = new MovePacket(Main.player.getLocation(),0,false,c.getId());
        if(child != null)
        {
            child.send(mess);
        }
        if(host != null)
        {
            host.broadcast(mess);
        }        
    }
    
    public class ClientListener implements MessageListener<Client>
    {
        public void messageReceived(Client source, Message message)
        {
            if (message instanceof ChatMessage)
            {
                final ChatMessage chatm = (ChatMessage) message;
                lund.printConsoleInfo("C#" + source.getId() + ": " + chatm.toString());
            }
            if (message instanceof MovePacket)
            {
                final MovePacket mo = (MovePacket) message;
                lund.findSpatial(Integer.toString(mo.idd)).setLocalTranslation(mo.move);
            }
        }
    }
    
    public class ServerListener implements MessageListener<HostedConnection>
    {
        public void messageReceived(HostedConnection source, Message message)
        {
            if (message instanceof ChatMessage)
            {
                ChatMessage chatm = (ChatMessage) message;
                lund.printConsoleInfo("C#" + source.getId() + ": " + chatm.text);
            }
        }
    }
    
    public void createServer(int port)
    {
        try
        {
            host = Network.createServer(port);
        } 
        catch (Throwable th)
        {
            lund.printConsoleError("Network Error: " + th.getMessage());
        }
        if(host != null)
        {
            host.addMessageListener(new ServerListener(), ChatMessage.class);
            host.addConnectionListener(new ServerStates());
            host.start();
        }
    }
    
    public void connectClient(String hostip, int port)
    {
        try
        {
            child = Network.connectToServer(hostip, port);
        }
        catch (Throwable th)
        {
            lund.printConsoleError("Network Error: " + th.getMessage());
        }
        if(child != null)
        {
            child.addMessageListener(new ClientListener(), ChatMessage.class);
            child.addClientStateListener(new ClientStates());
            child.start();
        }
    }
    
    public void close(int type)
    {
        switch(type)
        {
            case 1:
            {
                child.close();
            }
            case 2:
            {
                host.close();
            }
        }
    }
}
